package com.zwf.service;

import com.aspose.cells.SaveFormat;
import com.aspose.words.Document;
import com.aspose.words.SaveOptions;
import com.zwf.constant.FileConstant;
import com.zwf.utils.FileUtils;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
import java.util.Objects;

/**
 * 文件转换服务(doc,docx,xls,xlsx,txt转pdf)
 * 为什么转为PDF？ -> PDF可以直接在浏览器上展示
 */
@Service
public class FileConversionService {

    @Resource
    private LuceneIndexService indexService;

    /**
     * 处理多文件上传
     */
    public void processFileAsyncBatch(MultipartFile[] files) {
        for (MultipartFile file : files) {
            processFileAsync(file);
        }
    }

    /**
     * 处理单文件上传进行转换
     */
    public void processFileAsync(MultipartFile file) {
        try {
            if (FileConstant.fileSuffix.contains(getFileExtension(Objects.requireNonNull(file.getOriginalFilename()), 1))) {
                Path tempFile = Files.createTempFile(FileConstant.fullFilePath, "upload_", file.getOriginalFilename());
                file.getInputStream().transferTo(Files.newOutputStream(tempFile));
                Path outputPath = convertToPdf(tempFile, file.getOriginalFilename());
                Files.deleteIfExists(tempFile);

                Path dataDir = FileConstant.fullSysPath;
                if (Files.exists(dataDir)) {
                    indexService.buildIndex(dataDir);
                }
                System.out.println("生成pdf：" + outputPath);
            }
        } catch (Exception e) {
            throw new RuntimeException("文件转换失败：" + e);
        }
    }

    /**
     * 文件转换pdf
     */
    public Path convertToPdf(Path inputFile, String inputFileName) throws Exception {
        Path outputDir = FileConstant.fullSearchPath;
        if (!Files.exists(outputDir)) {
            Files.createDirectories(outputDir);
        }

        Path outputPath = outputDir.resolve(getFileExtension(inputFileName, 0) + ".pdf");
        if (inputFileName.contains("doc") || inputFileName.contains("docx") || inputFileName.contains("txt")) {
            extractWordContent(inputFile, outputPath);
        } else if (inputFileName.contains("xlsx") || inputFileName.contains("xls")) {
            extractExcelContent(inputFile, outputDir, outputPath);
        }

        return outputPath;
    }

    /**
     * Word转PDF
     */
    private void extractWordContent(Path inputFile, Path outputPath) throws Exception {
        File pdfFile = new File(outputPath.toAbsolutePath().toString());
        FileOutputStream os = new FileOutputStream(pdfFile);
        Document doc= new Document(inputFile.toAbsolutePath().toString());

        doc.save(os, SaveFormat.PDF);
        os.close();
    }

    /**
     * Excel转PDF, 先将Excel转为Word，Excel的每个Sheet都考虑到，生成到Word中，在将Word转PDF
     */
    public void extractExcelContent(Path inputFile, Path outputDir, Path outputFile) throws Exception {
        File excelFile = new File(inputFile.toAbsolutePath().toString());

        Path docOutputPath = outputDir.resolve(getFileExtension(inputFile.getFileName().toString(), 0) + ".docx");
        String docPath = docOutputPath.toString().toString();

        File pdfFile = new File(outputFile.toAbsolutePath().toString());
        FileOutputStream os = null;

        try (InputStream excelInputStream = Files.newInputStream(Path.of(excelFile.getPath()))) {
            os = new FileOutputStream(pdfFile);
            XSSFWorkbook wordbook = new XSSFWorkbook(excelInputStream);

            try (XWPFDocument wordDocument = new XWPFDocument()) {
                if(wordbook.getNumberOfSheets() == 0) {
                    throw new RuntimeException("文件为空");
                }
                for(int sheetIndex = 0;sheetIndex < wordbook.getNumberOfSheets(); sheetIndex++) {
                    Sheet sheet = wordbook.getSheetAt(sheetIndex);
                    String sheetName = sheet.getSheetName();

                    // 添加标题
                    wordDocument.createParagraph().createRun().setText("工作表：" + sheetName);

                    // 读取当前工作表的数据并插入到Word文档中, FileUtils直接写的工具类
                    List<List<String>> tableData = FileUtils.readExcel(sheet);
                    if (!tableData.isEmpty()) {
                        FileUtils.createTableInWord(wordDocument, tableData);
                    } else {
                        throw new RuntimeException("文件为空");
                    }
                }

                // 生成word文件
                wordDocument.write(new FileOutputStream(docPath));

                Document doc = new Document(docPath);
                doc.save(os, SaveFormat.PDF);
                Files.deleteIfExists(docOutputPath);// 删除Word文件
                os.close();
            }
        } catch (Exception e) {
            throw new RuntimeException(e.getMessage());
        }
    }

    /**
     * 处理文件后缀
     */
    private String getFileExtension(String fileName, int i) {
        int dotIndex = fileName.lastIndexOf(".");
        if (dotIndex == -1) {
            return "";
        }
        return (i == 1) ? fileName.substring(dotIndex + 1).toLowerCase() : fileName.substring(0, dotIndex).toLowerCase();
    }

}
